//
// Created by user on 20-5-4.
//

#ifndef _SPINLOCK_H_
#define _SPINLOCK_H_

#define localIrqSave(x)	__asm__ __volatile__("pushfq ; popq %0 ; cli":"=g"(x)::"memory")
#define localIrqRestore(x)	__asm__ __volatile__("pushq %0 ; popfq"::"g"(x):"memory")
#define localIrqDisable()	cli();
#define localIrqEnable()	sti();

#define spinLockIrqSave(lock, flags)	\
do					\
{					\
	localIrqSave(flags);		\
	spinLock(lock);		\
}while(0)

#define spinUnlockIrqRestore(lock, flags)	\
do						\
{						\
	spinUnlock(lock);			\
	localIrqRestore(flags);		\
}while(0)

#define spinLockIrq(lock)	\
do				\
{				\
	localIrqDisable();	\
	spinLock(lock);	\
}while(0)

#define spinUnlockIrq(lock)	\
do				\
{				\
	spinUnlock(lock);	\
	localIrqEnable();	\
}while(0)

typedef struct {
    __volatile__ unsigned long lock;        //1: unlock, 0: lock
} spinlock_T;

/**
 * 初始化自旋锁
 * @param lock 自旋锁指针
 */
void spinInit(spinlock_T *lock);

/**
 * 加锁
 * @param lock 自旋锁指针
 */
void spinLock(spinlock_T *lock);

/**
 * 解锁
 * @param lock 自旋锁指针
 */
void spinUnlock(spinlock_T *lock);

/**
 * 尝试获取自旋锁
 * @param lock 自旋锁指针
 * @return
 */
long spinTryLock(spinlock_T *lock);

#endif //_SPINLOCK_H_
